package wili.logic;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Coms21 {
	static int inc;

	static String readQT(String st, int startInd) {
		char ch = st.charAt(startInd);
		if (ch != '\'' && ch != '"')
			throw new RuntimeException("readQT:" + st.substring(startInd));
		int ind = st.indexOf(ch, startInd + 1) + 1;
		return st.substring(startInd, ind);
	}

	static boolean isIsolatedByNotId(String st, int start, int end) {
		//if (st.substring(start, end).matches("[\\$\\w]+")) {
		if (start == 0 || !Character.isJavaIdentifierPart(st.charAt(start - 1))) {
			if (end >= st.length() || !Character.isJavaIdentifierPart(st.charAt(end))) {
				return true;
			}
		}
		//}
		return false;
	}

	public static List<int[]> splitBy_asIndList(String op, String st, int from, int to,
			Map<Integer, Integer> skipInds) {
		List<int[]> ret = null;
		int from2 = from;
		f1: for (int i = from; i < to; i++) {
			if (skipInds != null) {
				Integer rInd = skipInds.get(i);
				if (rInd != null) {
					i = rInd - 1;
					continue;
				}
			}
			if (st.startsWith(op, i)) {
				if (ret == null)
					ret = new ArrayList<>();
				ret.add(new int[] { from2, i });
				from2 = i + op.length();
				i = from2 - 1;
				continue f1;
			}
		}
		if (from2 < to) {
			if (ret == null)
				ret = new ArrayList<>(1);
			ret.add(new int[] { from2, to });
		}
		return ret;
	}

	public static int[] trimAsInds(String s0, int from, int to) {
		for (int i = from; i < to; i++) {
			if (!Character.isSpaceChar(s0.charAt(i))) {
				from = i;
				break;
			}
		}
		for (int i = to - 1; i >= 0; i--) {
			if (!Character.isSpaceChar(s0.charAt(i)))
				return new int[] { from, i + 1 };
		}
		return null;
	}

	static int readBracketSimply(String s0, int start, char L, char R) {
		int left = 0;
		for (int i = start; i < s0.length(); i++) {
			//System.out.println(s0.substring(i));
			char ch = s0.charAt(i);
			if (ch == L) {
				++left;
			} else if (ch == R) {
				if (--left == 0)
					return i;
			} else if (ch == '\'' || ch == '"') {
				String qt = readQT(s0, i);
				i += qt.length() - 1;
			}
		}
		return -1;
	}

	static void add(String s0, int i, int j, List<SubStr> toList) {
		if (i == 7)
			Coms21.pause();
		toList.add(new SubStr(s0, i, j));
	}

	public static <T> int indexOf(char e, char[] ee) {
		for (int i = 0; i < ee.length; i++) {
			if (ee[i] == e)
				return i;
		}
		return -1;
	}

	public static <T> int indexOf(T e, T[] ee) {
		for (int i = 0; i < ee.length; i++) {
			if (ee[i] == e)
				return i;
		}
		return -1;
	}

	static List<SubStr> split(String s0, int start, int end, String... delims) {
		int[] inds = Coms21.trimAsInds(s0, start, end);
		start = inds[0];
		end = inds[1];
		if (start == 8)
			Coms21.pause();
		//char[] cc = s0.toCharArray();
		List<SubStr> ret = new ArrayList<>();
		int from = start;
		int inc2 = ++inc;
		if (inc2 == 7)
			pause();
		f1: for (int i = start; i < end; i++) {
			char ch = s0.charAt(i);
			if (ch == '"' || ch == '\'') {
				String qt = Coms21.readQT(s0, i);
				i += qt.length() - 1;
				continue;
			} else if (ch == '(') {
				int ind = Coms21.readBracketSimply(s0, i, '(', ')');
				if (ind <= i)
					Coms21.asert(false, s0.substring(i));
				if (i == start && ind == end - 1 && ret.isEmpty()) {
					//eg. (c|d)
					return split(s0, i + 1, end - 1, delims);
				} else {
					//eg. (c|d) and e
					i = ind;//保留左括，因为不一定终止于右括。eg. a,(b|c),f当终止于f后。
				}
				continue;
			} else if (Character.isSpaceChar(ch)) {
				continue;
			}
			for (String sp : delims) {
				if (s0.startsWith(sp, i)) {
					if (sp.matches("\\w+")) {
						if (!Coms21.isIsolatedByNotId(s0, i, i + sp.length())) {
							continue;
						}
					}
					Coms21.add(s0, from, i, ret);
					from = i + sp.length();
					i = from - 1;
					continue f1;
				}
			}
		}
		pause();
		String st = s0.substring(from, end).trim();
		if (st.length() > 0)
			Coms21.add(s0, from, end, ret);
		return ret;
	}

	static List<String> findAllReg(String regexp, int grp, String s0, int start, int maxTimes) {
		List<String> toList = null;
		Pattern pat = Pattern.compile(regexp);
		Matcher mat = pat.matcher(s0);
		mat.region(start, s0.length());
		int times = 0;
		while (mat.find()) {
			if (toList == null) {
				toList = new ArrayList<>(maxTimes < 0 ? 10 : maxTimes);
			}
			toList.add(mat.group(grp));
			if (maxTimes != -1 && ++times >= maxTimes)
				return toList;
		}
		return toList;
	}

	static void pause() {
	}

	static void asert(boolean is, String msg) {
		if (!is)
			throw new RuntimeException(msg);
	}
}